using AllIn1SpriteShader; using UnityEngine; using wildlogicgames; namespace RebelHeartEclipse { public enum CharacterID { Knight = 0, Rogue = 1, Bandit = 2, Bowman = 3, }; public enum CharacterIndicatorID { Blue_Squad = 0, Red_Quad = 1, }; public enum CharacterStateID { Idle, Move, Ready, Charge, Attack, PostAttack, Defend, Damaged, Dead, }; public enum CharacterShaderFXID { None = 0, Selected = 1, Hit = 2, }; public class CharacterObj : MonoBehaviour { private struct DeathFXData { public bool IS_PROCESSING; public int STEP; public Vector3 START_SCALE; public Vector3 TARGET_SCALE; public float DURATION; public float PROGRESS; public float ELAPSED_TIME; public void Reset(Vector3 initialScale, float stepDuration) { IS_PROCESSING = true; STEP = 0; START_SCALE = initialScale; TARGET_SCALE = initialScale; DURATION = stepDuration; PROGRESS = 0f; ELAPSED_TIME = 0f; } } public int _ID; public CharacterID _characterID; private CharacterStateID _stateID; private DeathFXData _deathFX; private CharacterShaderFXID _characterShaderFXID; private CharacterStat _charStatus; private GameObject _squadIndicatorObj; private bool _isPlayerCharacter; private const int _baseMoveAmount = 10; private int _movePointCount; private Transform _transform; private Vector3 _originalScale, _changedScale; private float _heightDiff, _widthDiff; private bool _movePosAdjustedAheadOfTime; private CameraController _cameraController; private SpriteRenderer _spriteRenderer; private Animator _animator; private Renderer _renderer; private Material _material; private RenderTexture _renderTex; [Header("Portrait Camera")] public Camera _localPortraitCamera; private GameObject _timerObj; private WTimer _timer; private const float _waitime = 0.25f;//0.25f; private const float _ChargeAnimTime = 2.25f; private const float _atkAnimTime = 1.2f; private const float _PostAttackAnimTime = 0.8f; private bool _process; private float _colourChangeFreq = 0.0125f; private const float _gradientBlendTarg = 0.6f; private float _gradientBlendAmount; private bool _increaseFreq, _processSpriteColourFX, _resetSpriteColourFX; private int _assignedGridX; private int _assignedGridY; private string _cachedIdleAnimStr = "_idle_anim"; private string _cachedMoveAnimStr = "_move_anim"; private string _cachedReadyAnimStr = "_ready_anim"; private string _cachedChargeAnimStr = "_charge_anim"; private string _cachedAttackAnimStr = "_attack_anim"; private string _cachedPostAttackAnimStr = "_atkFin_anim"; private string _cachedDamagedAnimStr = "_damaged_anim"; private void Awake() => Setup(); private void Start() { } private void Setup() { _transform = this.transform; _originalScale = _transform.localScale; _heightDiff = 0f; _heightDiff = 0f; _cameraController = Camera.main.GetComponent(); if (_spriteRenderer == null) _spriteRenderer = this.gameObject.GetComponent(); if (_animator == null) _animator = this.gameObject.GetComponent(); if (_renderer == null) _renderer = this.gameObject.GetComponent(); if (_material == null) _material = _renderer.material; //Use the unique instance for this obj, not shared. _timerObj = new GameObject(); _timerObj.AddComponent(); _timer = _timerObj.GetComponent(); //_timer.Reset(); //_timer.StartTimer(_waitime); _stateID = CharacterStateID.Idle; _characterShaderFXID = CharacterShaderFXID.None; _process = true; _gradientBlendAmount = 0f; _increaseFreq = true; _processSpriteColourFX = false; _resetSpriteColourFX = false; _assignedGridX = 0; _assignedGridY = 0; _renderTex = new RenderTexture(128, 128, 24, RenderTextureFormat.ARGB32); _renderTex.Create(); _localPortraitCamera.targetTexture = _renderTex; //_localPortraitCamera = this.gameObject.GetComponentInChildren _charStatus = new CharacterStat(); _movePointCount = _baseMoveAmount; } void LateUpdate() { _transform.LookAt(_transform.position + Camera.main.transform.rotation * Vector3.forward, Camera.main.transform.rotation * Vector3.up); } private void Update() { if (!_process) return; SpriteColourFXUpdate(); AnimationUpdate(); IndicatorUpdate(); } private void IndicatorUpdate() { if (EventManager.GetEventFlag() == EventFlagID.EventFlag_Process_Player_Attack || EventManager.GetEventFlag() == EventFlagID.EventFlag_Update_UI_Status) { if (_squadIndicatorObj == null) return; if (_squadIndicatorObj.activeSelf) _squadIndicatorObj.SetActive(false); } if (EventManager.GetEventFlag() == EventFlagID.EventFlag_Idle) { if (_squadIndicatorObj == null) return; if (!_squadIndicatorObj.activeSelf) _squadIndicatorObj.SetActive(true); } } private void AnimTimerUpdate() { if (!_isPlayerCharacter) return; if (_timer.HasTimerFinished(true)) { if (_charStatus._characterClass == CharacterClass.Bowman) { _stateID = CharacterStateID.Idle; EventManager.SetEventFlag(EventFlagID.EventFlag_Update_UI_Status); //_cameraController.InitShakeFX(1.0f, 0.05f); ObjPooler._instance.InstantiateObj(PooledObjID.ArrowObj, this._transform, _transform.rotation); //_cameraController.transform.LookAt(this._transform.position); _cameraController.SetPivotPoint(this._transform.position); return; } if (_stateID == CharacterStateID.Charge) { _stateID = CharacterStateID.Attack; _timer.Reset(); _timer.StartTimer(_atkAnimTime); _transform.localScale = _originalScale; return; } if (_stateID == CharacterStateID.Attack) { _stateID = CharacterStateID.PostAttack; _timer.Reset(); _timer.StartTimer(_PostAttackAnimTime); _cameraController.InitShakeFX(); return; } if (_stateID == CharacterStateID.PostAttack) { //_transform.localScale = _originalScale; _stateID = CharacterStateID.Idle; //_cameraController.InitShakeFX(); EventManager.SetEventFlag(EventFlagID.EventFlag_Update_UI_Status); return; } } } private void AnimationUpdate() { if (_characterID == CharacterID.Rogue) return; AnimTimerUpdate(); if (EventManager.GetEventFlag() == EventFlagID.EventFlag_Idle) _stateID = CharacterStateID.Idle; switch (_stateID) { case CharacterStateID.Idle: _animator.Play(_cachedIdleAnimStr); break; case CharacterStateID.Move: _animator.Play(_cachedMoveAnimStr); break; case CharacterStateID.Ready: _animator.Play(_cachedReadyAnimStr); break; case CharacterStateID.Charge: _animator.Play(_cachedChargeAnimStr); break; case CharacterStateID.Attack: _animator.Play(_cachedAttackAnimStr); break; case CharacterStateID.PostAttack: _animator.Play(_cachedPostAttackAnimStr); break; case CharacterStateID.Damaged: _animator.Play(_cachedDamagedAnimStr); break; case CharacterStateID.Dead: _animator.Play(_cachedDamagedAnimStr); if (!_deathFX.IS_PROCESSING) { _deathFX.Reset(_originalScale, 0.125f); //0.15 sec per step InitDeathStepFX(_originalScale); ObjPooler._instance.InstantiateObj(PooledObjID.BloodObj, this._transform, _transform.rotation); _timer.Reset(); _timer.StartTimer(_waitime); } DeathFXUpdate(); break; } return; } public void FlipSpriteX(bool b) => _spriteRenderer.flipX = b; private void CheckForResetUpdate() { switch(_stateID) { case CharacterStateID.Idle: if (EventManager.GetGridCellClicked_X() != _assignedGridX || EventManager.GetGridCellClicked_Y() != _assignedGridY) { ResetSpriteColourFXSettings(); } break; case CharacterStateID.Damaged: //_gradientBlendAmount = 0f; //SetMaterialProperties(); //_processSpriteColourFX = false; //_increaseFreq = true; break; } } private void ResetSpriteColourFXSettings() { _gradientBlendAmount = 0f; SetMaterialProperties(); _processSpriteColourFX = false; _increaseFreq = true; //if (_stateID != CharacterStateID.Damaged) _characterShaderFXID = CharacterShaderFXID.None; } private void SpriteColourFXUpdate() { if (!_processSpriteColourFX) return; CheckForResetUpdate(); if (_increaseFreq) { if (_gradientBlendAmount < _gradientBlendTarg) { SetMaterialProperties(); _gradientBlendAmount += _colourChangeFreq; } else { _increaseFreq = false; } return; } if (!_increaseFreq) { if (_gradientBlendAmount > 0.01f) { SetMaterialProperties(); _gradientBlendAmount -= _colourChangeFreq; } else { _increaseFreq = true; } return; } } private void SetMaterialProperties() { if (_renderer == null) return; if (_material == null) return; //_GradBlend if (_characterShaderFXID == CharacterShaderFXID.Selected) { _colourChangeFreq = 0.0125f; _material.SetFloat("_GradBlend", _gradientBlendAmount); } if (_characterShaderFXID == CharacterShaderFXID.Hit) { _colourChangeFreq = 0.025f; _material.SetFloat("_HitEffectBlend", _gradientBlendAmount); } } public void InitSelectionFX(int x, int y) { _assignedGridX = x; _assignedGridY = y; EventManager.SetSelectedCharacterCell(_assignedGridX, _assignedGridY); _processSpriteColourFX = true; SetMaterialProperties(); _characterShaderFXID = CharacterShaderFXID.Selected; if (_isPlayerCharacter) { EventManager.SetCurrentPlayerCell(x, y); } //_timer.Reset(); //_timer.StartTimer(_waitime); //_material.SetColor("GRADIENT_ON", Color.green); } public void InitDamagedFX() { _processSpriteColourFX = true; SetMaterialProperties(); _characterShaderFXID = CharacterShaderFXID.Hit; //ObjPooler._instance.InstantiateObj(PooledObjID.BloodObj, this._transform, _transform.rotation); } public bool InitAttackFX() { if (_stateID == CharacterStateID.Charge) return false; if (_stateID == CharacterStateID.Attack) return false; if (_stateID == CharacterStateID.PostAttack) return false; _timer.Reset(); _timer.StartTimer(_ChargeAnimTime); _stateID = CharacterStateID.Charge; if (_charStatus._characterClass == CharacterClass.Knight) { _changedScale = _transform.localScale; _changedScale.x = _changedScale.x * 1.15f; _changedScale.y = _changedScale.y * 1.15f; _transform.localScale = _changedScale; } return true; } private void InitDeathStepFX(Vector3 target) { _deathFX.START_SCALE = _transform.localScale; _deathFX.TARGET_SCALE = target; _deathFX.PROGRESS = 0f; _deathFX.ELAPSED_TIME = 0f; } private void DeathFXUpdate() { if (!_deathFX.IS_PROCESSING) return; _deathFX.ELAPSED_TIME += Time.deltaTime; _deathFX.PROGRESS = Mathf.Clamp01(_deathFX.ELAPSED_TIME / _deathFX.DURATION); _transform.localScale = Vector3.Lerp(_deathFX.START_SCALE, _deathFX.TARGET_SCALE, _deathFX.PROGRESS); //Current step complete, now the next. if (_deathFX.PROGRESS >= 1f) { _deathFX.STEP++; switch (_deathFX.STEP) { case 1: InitDeathStepFX(RandomWildDeathScale()); break; case 2: InitDeathStepFX(RandomWildDeathScale()); break; case 3: InitDeathStepFX(RandomWildDeathScale()); break; case 4: InitDeathStepFX(RandomWildDeathScale()); break; case 5: InitDeathStepFX(RandomWildDeathScale()); break; case 6: InitDeathStepFX(Vector3.zero); break; case 7: _deathFX.IS_PROCESSING = false; gameObject.SetActive(false); break; } } if (_timer.HasTimerFinished(true)) { _timer.Reset(); _timer.StartTimer(_waitime); ObjPooler._instance.InstantiateObj(PooledObjID.BloodObj, this._transform, _transform.rotation); } } private Vector3 RandomWildDeathScale() { float minX = -3.0f; float maxX = 4.0f; float minY = 0.1f; float maxY = 7.0f; float x = _originalScale.x * UnityEngine.Random.Range(minX, maxX); float y = _originalScale.y * UnityEngine.Random.Range(minY, maxY); return new Vector3(x, y, 1f); } public void SetID(int id) => _ID = id; public int GetID() => _ID; public bool IsPlayerCharacter() => _isPlayerCharacter; public void InitClassStatus(bool isPlayerCharacter, CharacterClass classStat, int classLevel, GameObject squadIndicatorObj, int id, float heightDiff, float widthDiff) { _isPlayerCharacter = isPlayerCharacter; _charStatus.InitStatus(classStat, classLevel); _squadIndicatorObj = squadIndicatorObj; _ID = id; _heightDiff = heightDiff; _widthDiff = widthDiff; switch (classStat) { case CharacterClass.Knight: _cachedIdleAnimStr = "knight_idle_anim"; _cachedMoveAnimStr = "knight_move_anim"; _cachedReadyAnimStr = "knight_ready_anim"; _cachedChargeAnimStr = "knight_charge_anim"; _cachedAttackAnimStr = "knight_attack_anim"; _cachedPostAttackAnimStr = "knight_atkFin_anim"; _cachedDamagedAnimStr = "knight_damaged_anim"; break; case CharacterClass.Bowman: _cachedIdleAnimStr = "bowman_idle_anim"; _cachedMoveAnimStr = "bowman_move_anim"; _cachedReadyAnimStr = "bowman_ready_anim"; _cachedChargeAnimStr = "bowman_aiming_anim"; _cachedAttackAnimStr = "bowman_attack_anim"; _cachedPostAttackAnimStr = "bowman_atkFin_anim"; _cachedDamagedAnimStr = "bowman_damaged_anim"; break; case CharacterClass.Bandit: _cachedIdleAnimStr = "bandit_idle_anim"; _cachedMoveAnimStr = "bandit_move_anim"; _cachedReadyAnimStr = "bandit_ready_anim"; _cachedChargeAnimStr = "bandit_aiming_anim"; _cachedAttackAnimStr = "bandit_attack_anim"; _cachedPostAttackAnimStr = "bandit_atkFin_anim"; _cachedDamagedAnimStr = "bandit_damaged_anim"; break; case CharacterClass.Rogue: break; } } public void SetState(CharacterStateID characterStateID) => _stateID = characterStateID; public CharacterStateID GetState() => _stateID; public string GetCharacterClassStr() //=> { if (_charStatus._characterClass == CharacterClass.Bandit) return "Bandit"; if (_charStatus._characterClass == CharacterClass.Rogue) return "Rogue"; if (_charStatus._characterClass == CharacterClass.Bowman) return "Bowman"; if (_charStatus._characterClass == CharacterClass.Knight) return "Knight"; return ""; } public string GetCharacterLevelStr() //=> { string str = "0"; str = _charStatus._characterLevel.ToString(); return str; } public string GetCharacterHPTotalStr() //=> { string str = "0"; str = _charStatus._hitPointTotal.ToString(); return str; } public string GetCharacterHPCurrentStr() //=> { string str = "0"; str = _charStatus._hitPointCurrent.ToString(); return str; } public void DeductHP(int dmg) //=> _charStatus.DeductHealthPoints(dmg); { _charStatus.DeductHealthPoints(dmg); //SetState(CharacterStateID.Damaged); } public int GetTotalHP() => _charStatus._hitPointTotal; public int GetCurrentHP() => _charStatus._hitPointCurrent; public CharacterStat GetCharacterStat() => _charStatus; public RenderTexture GetPortraitRenderTex() => _renderTex; public void SetPosition(Vector3 newPosition)// => _transform.position = newPosition; { if (!_movePosAdjustedAheadOfTime) { newPosition.y += _heightDiff; newPosition.x += _widthDiff; newPosition.z += _widthDiff; } _transform.position = newPosition; newPosition.y -= 0.1f; newPosition.x -= 0.09f; newPosition.z -= 0.09f; _squadIndicatorObj.transform.position = newPosition; } public Vector3 GetAdjustedPosition(Vector3 newPosition) { newPosition.y += _heightDiff; newPosition.x += _widthDiff; newPosition.z += _widthDiff; _movePosAdjustedAheadOfTime = true; return newPosition; } public float GetHeightDifference() => _heightDiff; public int GetMovePtCount() => _movePointCount; public void ResetMovePtsCount() => _movePointCount = _baseMoveAmount; public void DecreaseMovePtsCount() => _movePointCount--; public void IncreaseMovePtsCount() => _movePointCount++; public int GetAssignedGridX() => _assignedGridX; public int GetAssignedGridY() => _assignedGridY; } }